package models

import (
	"database/sql"
	"errors"
	"fmt"
	"image-server/config"
	"image-server/dao/model"
	util "image-server/utils"
	"path"
	"path/filepath"
	"strings"
	"time"
)

// CreateImageWithFiles 完整创建图片记录（包含文件上传和数据库存储）
func CreateImageWithFiles(
	image *model.Image,
	originalContent []byte,
	thumbContent []byte,
) (int64, error) {
	// 1. 生成缩略图存储路径
	if len(thumbContent) > 0 && image.ThumbOssKey == "" {
		ext := filepath.Ext(image.OssKey)
		image.ThumbOssKey = strings.TrimSuffix(image.OssKey, ext) + "_thumb" + ext
		image.ThumbFileSize = int64(len(thumbContent))
	}

	// 2. 上传原图到OSS
	if err := util.UploadToOSS(image.OssKey, originalContent); err != nil {
		return 0, fmt.Errorf("上传原图失败: %w", err)
	}

	// 3. 上传缩略图到OSS（失败则回滚原图）
	if len(thumbContent) > 0 {
		if err := util.UploadToOSS(image.ThumbOssKey, thumbContent); err != nil {
			_ = util.DeleteFromOSS(image.OssKey) // 回滚操作
			return 0, fmt.Errorf("上传缩略图失败: %w", err)
		}
	}

	// 4. 保存记录到数据库（失败则回滚所有文件）
	image.CreatedAt = time.Now()
	result, err := config.DB.Exec(
		`INSERT INTO images 
		 (album_id, user_id, title, description, tags,
		  oss_key, file_name, file_size, 
		  thumb_oss_key, thumb_file_size, created_at) 
		 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
		image.AlbumID, image.UserID, image.Title,
		image.Description, image.Tags,
		image.OssKey, image.FileName, image.FileSize,
		image.ThumbOssKey, image.ThumbFileSize,
		image.CreatedAt,
	)
	if err != nil {
		// 回滚已上传的文件
		_ = util.DeleteFromOSS(image.OssKey)
		if image.ThumbOssKey != "" {
			_ = util.DeleteFromOSS(image.ThumbOssKey)
		}
		return 0, fmt.Errorf("保存图片记录失败: %w", err)
	}

	return result.LastInsertId()
}

// GetImageByID 根据ID查询图片信息
func GetImageByID(id int64) (*model.Image, error) {
	var img model.Image
	err := config.DB.QueryRow(
		`SELECT id, album_id, user_id, title, oss_key, file_name, file_size, thumb_oss_key, thumb_file_size, created_at 
		 FROM images WHERE id = ?`,
		id,
	).Scan(
		&img.ID, &img.AlbumID, &img.UserID, &img.Title,
		&img.OssKey, &img.FileName, &img.FileSize, &img.ThumbOssKey, &img.ThumbFileSize, &img.CreatedAt,
	)
	if err == sql.ErrNoRows {
		return nil, errors.New("图片不存在")
	}
	return &img, err
}

func UpdateImage(image *model.Image) error {
	// 1. 查询旧图片信息
	oldImage, err := GetImageByID(image.ID)
	if err != nil {
		return err
	}
	// 2. 如果标题变更，处理OSS文件名更新
	var newOSSKey, newThumbOSSKey string
	if image.Title != oldImage.Title {
		// 生成新的文件名
		newFileName := util.SanitizeFileName(image.Title) + path.Ext(oldImage.FileName)

		// 生成新的OSS路径
		oldOSSKeyDir := path.Dir(oldImage.OssKey)
		newOSSKey = path.Join(oldOSSKeyDir, newFileName)

		// 生成新的缩略图OSS路径
		ext := filepath.Ext(newOSSKey)
		newThumbOSSKey = strings.TrimSuffix(newOSSKey, ext) + "_thumb" + ext

		fmt.Println(oldImage.OssKey)
		fmt.Println(newOSSKey)
		fmt.Println(oldImage.ThumbOssKey)
		fmt.Println(newThumbOSSKey)

		// 重命名OSS文件
		if err := util.RenameOSSObject(oldImage.OssKey, newOSSKey); err != nil {
			return fmt.Errorf("重命名OSS文件失败: %w", err)
		}
		if err := util.RenameOSSObject(oldImage.ThumbOssKey, newThumbOSSKey); err != nil {
			return fmt.Errorf("重命名缩略图文件失败: %w", err)
		}
	}
	// 3. 执行数据库更新
	_, err = config.DB.Exec(
		`UPDATE images 
		 SET title = ?, description = ?, tags = ?, 
		     oss_key = COALESCE(?, oss_key), 
		     thumb_oss_key = COALESCE(?, thumb_oss_key)
		 WHERE id = ? AND user_id = ?`,
		image.Title,
		image.Description,
		image.Tags,
		newOSSKey,      // 新的原图路径（若无变更则为NULL）
		newThumbOSSKey, // 新的缩略图路径（若无变更则为NULL）
		image.ID,
		image.UserID, // 验证所有者身份
	)
	if err != nil {
		return fmt.Errorf("数据库更新失败: %w", err)
	}
	return nil
}

// DeleteImageByID 删除图片（含OSS文件和数据库记录）
func DeleteImageByID(id, userID int64) error {
	// 1. 查询图片完整信息
	img, err := GetImageByID(id)
	if err != nil {
		return err
	}

	// 2. 验证权限
	if img.UserID != userID {
		return errors.New("无删除权限")
	}

	// 3. 删除OSS中的原图
	if img.OssKey != "" {
		if err := util.DeleteFromOSS(img.OssKey); err != nil {
			return fmt.Errorf("删除原图失败: %w", err)
		}
	}

	// 4. 删除OSS中的缩略图
	if img.ThumbOssKey != "" {
		if err := util.DeleteFromOSS(img.ThumbOssKey); err != nil {
			return fmt.Errorf("删除缩略图失败: %w", err)
		}
	}

	// 5. 删除数据库记录
	_, err = config.DB.Exec(
		"DELETE FROM images WHERE id = ? AND user_id = ?",
		id, userID,
	)
	return err
}

// GetImagesByAlbumID 按相册ID查询图片（分页）
func GetImagesByAlbumID(albumID int64, page, limit int) ([]model.Image, int64, error) {
	offset := (page - 1) * limit

	// 1. 查询图片列表
	rows, err := config.DB.Query(
		`SELECT 
			id, album_id, user_id, title, description, tags,
			oss_key, file_name, file_size, 
			thumb_oss_key, thumb_file_size, created_at 
		 FROM images 
		 WHERE album_id = ? 
		 ORDER BY created_at DESC 
		 LIMIT ? OFFSET ?`,
		albumID, limit, offset,
	)
	if err != nil {
		return nil, 0, fmt.Errorf("查询图片列表失败: %w", err)
	}
	defer rows.Close()

	// 2. 解析查询结果
	var images []model.Image
	for rows.Next() {
		var img model.Image
		if err := rows.Scan(
			&img.ID, &img.AlbumID, &img.UserID, &img.Title,
			&img.Description, &img.Tags,
			&img.OssKey, &img.FileName, &img.FileSize,
			&img.ThumbOssKey, &img.ThumbFileSize,
			&img.CreatedAt,
		); err != nil {
			return nil, 0, fmt.Errorf("解析图片信息失败: %w", err)
		}
		images = append(images, img)
	}

	// 检查行迭代错误
	if err := rows.Err(); err != nil {
		return nil, 0, fmt.Errorf("遍历图片记录失败: %w", err)
	}

	// 3. 查询总条数
	var total int64
	err = config.DB.QueryRow(
		"SELECT COUNT(*) FROM images WHERE album_id = ?",
		albumID,
	).Scan(&total)
	if err != nil {
		return nil, 0, fmt.Errorf("查询图片总数失败: %w", err)
	}

	return images, total, nil
}

// DeleteImagesByAlbumID 按相册ID删除所有图片
func DeleteImagesByAlbumID(albumID int64) error {
	// 1. 查询所有图片的OSS路径
	rows, err := config.DB.Query(
		"SELECT oss_key, thumb_oss_key FROM images WHERE album_id = ?",
		albumID,
	)
	if err != nil {
		return fmt.Errorf("查询图片信息失败: %w", err)
	}
	defer rows.Close()

	// 收集需要删除的OSS路径
	var allOssKeys []string
	for rows.Next() {
		var ossKey, thumbOssKey string
		if err := rows.Scan(&ossKey, &thumbOssKey); err != nil {
			return fmt.Errorf("读取图片信息失败: %w", err)
		}
		if ossKey != "" {
			allOssKeys = append(allOssKeys, ossKey)
		}
		if thumbOssKey != "" {
			allOssKeys = append(allOssKeys, thumbOssKey)
		}
	}

	// 检查行迭代错误
	if err := rows.Err(); err != nil {
		return fmt.Errorf("遍历图片记录失败: %w", err)
	}

	// 2. 批量删除OSS中的原图和缩略图
	if len(allOssKeys) > 0 {
		if err := util.DeleteObjects(allOssKeys); err != nil {
			return fmt.Errorf("批量删除图片（含缩略图）失败: %w", err)
		}
	}

	// 3. 删除数据库中该相册的所有图片记录
	_, err = config.DB.Exec("DELETE FROM images WHERE album_id = ?", albumID)
	if err != nil {
		return fmt.Errorf("删除数据库图片记录失败: %w", err)
	}

	return nil
}
